#ifndef __MEM_H__
#define __MEM_H__

#include "thread.h"
#include "redobject.h"

#define OS_FREE				free
#define OS_MALLOC			malloc

#define MEM_MAX_MEMORY		(1 * 1024 * 1024 * 1024) /* max memory usage: 1 GB */

typedef enum _RedMemoryClass
{
	mc_32,
	mc_64,
	mc_80,
	mc_96,
	mc_144,
	mc_256,
	mc_512,
	mc_4k,
	mc_16k,
	mc_64k,
	mc_256k,
	mc_1M,
	mc_4M,
	mc_16M,
	mc_unmanaged,

	RedMemoryClassStart = mc_32,
	RedMemoryClassCount = mc_unmanaged,
} RedMemoryClass;

typedef struct _RedMemoryNode RedMemoryNode;
typedef struct _RedMemoryPool RedMemoryPool;

typedef struct _RedMemoryNode
{
	RedMemoryNode	*next;
	RedMemoryNode	*prev;

	size_t			 size;
	RedMemoryPool	*pool;
	RedMemoryClass	 class;
} RedMemoryNode;

typedef struct _RedMemoryPool
{
	RedMemoryPool	*prev;
	RedMemoryPool	*next;

	int				 usage;
	RedMemoryClass	 class;
} RedMemoryPool;

typedef struct _RedMemoryInfo
{
	RedMemoryPool	 pool;
	RedMemoryNode	 free;
	RedMemoryNode	 using;

	int				 available;
	int				 allocated;

	RedSpin			 spin_node;
	RedMutex		 mutex_pool;
} RedMemoryDesc;

typedef struct _RedMemoryState
{
	size_t			 malloc;
	size_t			 objects;
	RedMemoryDesc	 classes[RedMemoryClassCount];
} RedMemoryState;

RED_EXPORT extern size_t RedMem_MaxMemory;
RED_EXPORT extern RedMemoryState Red_MemoryState;

RED_EXPORT void Red_FreeMemoryPool(void);
RED_EXPORT void Red_InitMemoryPool(void);

RED_EXPORT void RedMem_Free(void *ptr);
RED_EXPORT void *RedMem_Alloc(size_t size);
RED_EXPORT void *RedMem_Resize(void *ptr, size_t size);
RED_EXPORT void *RedMem_Realloc(void *ptr, size_t size);

#endif /* __MEM_H__ */
